﻿module Core

    type Expr = | Plus of Expr * Expr
                | Times of Expr * Expr
                | Var of int
                | Zero
                | One

    type Cmd = | Skip
               | Asgn of int * Expr
               | Choice of Cmd * Cmd
               | Seq  of Cmd * Cmd
               | Loop of int * Cmd
               | Goto of string
               | Label of string

    let rec NumOfVarsInExpression = function
        | Var(i)        -> i
        | Zero          -> 1
        | One           -> 1
        | Plus(e1,e2)   -> max (NumOfVarsInExpression e1) (NumOfVarsInExpression e2)
        | Times(e1, e2) -> max (NumOfVarsInExpression e1) (NumOfVarsInExpression e2)

    and NumOfVars = function
        | Skip          -> 1
        | Asgn(j,e)     -> max j (NumOfVarsInExpression e)
        | Seq(C1,C2)    -> max (NumOfVars C1) (NumOfVars C2)
        | Choice(C1,C2) -> max (NumOfVars C1) (NumOfVars C2)
        | Loop(l,C)     -> max l (NumOfVars C)
        | Goto(_)       -> 1
        | Label(_)      -> 1